<template>
  <!-- 多标签卡片 -->
  <div class="tag-card">
    <div class="tag-header">
      <div class="header-left">
        <span class="header-icon">🏷️</span>
        <h3 class="title">文章标签</h3>
      </div>
      <span class="total">共 {{ tags.length }} 个标签</span>
    </div>

    <div ref="sphereEl" class="tag-sphere" @mousedown="handleMouseDown">
      <div
        v-for="(item, index) in tags"
        :key="index"
        class="tag-item"
        :class="{ 'is-hovered': hoveredTag === item.name }"
        :style="{
          backgroundColor: getTagColor(index),
          fontSize: `${getTagSize(item.count)}rem`,
        }"
        @mouseenter="handleTagHover(item.name)"
        @mouseleave="handleTagLeave"
      >
        {{ item.name }} <span class="tag-count">{{ item.count }}</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { getTagsService } from "@/api/Home";
import { ref, onMounted, onUnmounted } from "vue";

const tags = ref([]);
const sphereEl = ref(null);
const radius = 120; // 增大球体半径
const depth = 2 * radius;
const size = ref({ width: 0, height: 0 });
const tagPositions = ref([]);
const rotation = ref({ x: 0, y: 0 });
const isMouseDown = ref(false);
const hoveredTag = ref(null);
const isHovering = ref(false);
let animationFrame;
let lastMousePosition = { x: 0, y: 0 };

// 标签颜色数组
const tagColors = [
  "#3498db",
  "#e74c3c",
  "#2ecc71",
  "#f39c12",
  "#9b59b6",
  "#1abc9c",
  "#d35400",
  "#34495e",
];

// 获取标签颜色
const getTagColor = (index) => {
  return tagColors[index % tagColors.length];
};

// 修改initTags函数，调整分布密度
const initTags = () => {
  const total = tags.value.length;
  const goldenRatio = (1 + Math.sqrt(5)) / 2;

  tagPositions.value = tags.value.map((tag, i) => {
    // 增加y值的压缩度
    const y = 1.1 - (i / (total - 1)) * 2.2; // y范围从1.1到-1.1

    // 增加半径压缩度
    const radiusAtY = Math.sqrt(1 - Math.pow(y / 1.1, 2)) * 0.9;

    const theta = (2 * Math.PI * i) / goldenRatio;

    return {
      x: Math.cos(theta) * radiusAtY * radius,
      y: y * radius * 0.8, // 垂直方向也压缩一点
      z: Math.sin(theta) * radiusAtY * radius,
      tag,
    };
  });
};

// 修改getTagSize函数，增大基础尺寸
const getTagSize = (count) => {
  const maxCount = Math.max(...tags.value.map((tag) => tag.count));
  const minSize = 1.0; // 从0.8增大到1.0
  const maxSize = 1.6; // 从1.4增大到1.6
  return minSize + (count / maxCount) * (maxSize - minSize);
};

// 更新标签位置
const updateTagsPosition = () => {
  if (!sphereEl.value) return;

  const centerX = size.value.width / 2;
  const centerY = size.value.height / 2;
  const maxOffset = Math.min(centerX, centerY) * 0.9;

  tagPositions.value.forEach((tagData, i) => {
    const el = sphereEl.value.children[i];
    if (!el) return;

    const rx = (rotation.value.x * Math.PI) / 180;
    const ry = (rotation.value.y * Math.PI) / 180;

    const y1 = tagData.y * Math.cos(rx) - tagData.z * Math.sin(rx);
    const z1 = tagData.y * Math.sin(rx) + tagData.z * Math.cos(rx);

    const x1 = tagData.x * Math.cos(ry) - z1 * Math.sin(ry);
    const z2 = tagData.x * Math.sin(ry) + z1 * Math.cos(ry);

    const scale = Math.max(0.6, (depth + z2) / (2 * depth));
    const opacity = Math.max(0.5, (z2 + radius) / (2 * radius));

    const hoverScale = hoveredTag.value === tagData.tag.name ? 1.5 : 1;
    const hoverOpacity = hoveredTag.value
      ? hoveredTag.value === tagData.tag.name
        ? 1
        : 0.3
      : opacity;

    el.style.transform = `
      translate(-50%, -50%)
      translate3d(${x1}px, ${y1}px, 0)
      scale(${scale * hoverScale})
    `;
    el.style.opacity = hoverOpacity;
    el.style.zIndex = Math.floor((z2 + radius) * 100);
  });
};

// 鼠标事件处理
const handleMouseDown = (e) => {
  isMouseDown.value = true;
  lastMousePosition = { x: e.clientX, y: e.clientY };
};

const handleMouseMove = (e) => {
  if (!isMouseDown.value) return;

  const deltaX = e.clientX - lastMousePosition.x;
  const deltaY = e.clientY - lastMousePosition.y;

  rotation.value.x += deltaY * 0.5;
  rotation.value.y += deltaX * 0.5;

  lastMousePosition = { x: e.clientX, y: e.clientY };
};

const handleMouseUp = () => {
  isMouseDown.value = false;
};

// 标签悬停效果
const handleTagHover = (tagName) => {
  hoveredTag.value = tagName;
  isHovering.value = true;
};

const handleTagLeave = () => {
  hoveredTag.value = null;
  isHovering.value = false;
};

// 窗口大小变化处理
const handleResize = () => {
  if (sphereEl.value) {
    size.value = {
      width: sphereEl.value.clientWidth,
      height: sphereEl.value.clientHeight,
    };
  }
};

// 动画循环
const animate = () => {
  if (!isMouseDown.value && !isHovering.value) {
    rotation.value.y += 0.2;
  }
  updateTagsPosition();
  animationFrame = requestAnimationFrame(animate);
};

// 获取标签数据
const getTags = async () => {
  try {
    const { data } = await getTagsService();
    tags.value = data;
    initTags();
  } catch (error) {
    console.error("获取标签失败:", error);
  }
};

onMounted(() => {
  getTags();

  if (sphereEl.value) {
    size.value = {
      width: sphereEl.value.clientWidth,
      height: sphereEl.value.clientHeight,
    };
  }

  // 初始化动画
  animate();

  // 添加事件监听
  window.addEventListener("mouseup", handleMouseUp);
  window.addEventListener("mousemove", handleMouseMove);
  window.addEventListener("resize", handleResize);
});

onUnmounted(() => {
  cancelAnimationFrame(animationFrame);
  window.removeEventListener("mouseup", handleMouseUp);
  window.removeEventListener("mousemove", handleMouseMove);
  window.removeEventListener("resize", handleResize);
});
</script>

<style lang="scss" scoped>
.tag-card {
  margin-top: 24px;
  padding: 20px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}

.tag-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;

  .header-left {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .header-icon {
    font-size: 1.2rem;
  }

  .title {
    margin: 0;
    font-size: 1.1rem;
    font-weight: 600;
    color: #333;
  }

  .total {
    font-size: 0.9rem;
    color: #666;
  }
}

.tag-sphere {
  position: relative;
  width: 100%;
  height: 260px;
  margin: auto;
  perspective: 1000px;
  cursor: grab;
  overflow: hidden;
  border-radius: 8px;

  &:active {
    cursor: grabbing;
  }
}

.tag-item {
  position: absolute;
  top: 50%;
  left: 50%;
  transform-origin: center;
  padding: 6px 12px;
  color: white;
  border-radius: 20px;
  font-weight: 500;
  transition: all 0.3s ease;
  white-space: nowrap;
  user-select: none;
  will-change: transform, opacity;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;

  &.is-hovered {
    z-index: 1000;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
  }

  .tag-count {
    margin-left: 5px;
    font-size: 0.8em;
    opacity: 0.8;
  }
}

@media (max-width: 768px) {
  .tag-sphere {
    height: 250px;
  }

  .tag-item {
    padding: 4px 8px;
    font-size: 0.9rem;
  }
}
</style>